import Configer from "../apiModel/config/Configer";
import {ConfigKey} from "../../constant/ConfigConstant";
import {Attrs, CombinationInfo, GameType, ItemShopInfo, OrderStr, TaskApplyData, VestJson} from "../../type/Type";
import {CastType1, PlayerAttribute, UnitAttribute} from "./DataModel";
import {
    LIVERoomItem,
    RPGRoomItem,
    SerializeBodyHistory,
    StoreSerializeBody
} from "../../controller/model/SerializeBody";
import {AbilityJson, ItemJson, UnitJson} from "../apiModel/model/StoreJson";
import {ControllerNo} from "../../controller/model/ControllerOpt";
import MathUtil from "../codeAdapter/MathUtil";
import {UnitModel} from "../apiModel/adapterModel/model3/UnitModel";
import {EffectModel} from "../apiModel/adapterModel/model2/EffectModel";
import {LocModel} from "../apiModel/base/LocModel";
import {ItemModel} from "../apiModel/adapterModel/model3/ItemModel";

export enum PlayerDataKey {
    // 单位相关
    clearFightTime = 1,
    // 单位羁绊
    unitCombination,
    // 召唤物
    summoned,
    // 巡逻数组
    patro,
    // 宠物
    pet,
    // 宠物信息
    petInfo,

    // 初始化时可供选择的单位信息
    initUnitPoolData,

    // UI背包
    goodsBag,

    // 任务相关
    // 单位接收任务信息
    unitApplyTask,


    // 成就相关
    // 成就增加的属性
    // achievementAttr,
    // 已完成的成就
    achievements,

    // 成就受益人(宠物)
    achievementPetAttr,
    // 成就受益人(英雄)
    achievementHeroAttr,
    // 成就受益人(召唤物)
    achievementSummonAttr,

    handBook,
    handBookExp,
    integral,
    integralCache,
    // 未处理
    // Unit中
    // attackCallBack 触发统一处理
    // caluTaskMap   需要一个统一的防抖队列
    // goodItemMaps  item与框架需要保存的信息需要换一种关联方式

    // 存档相关
    storeHistory,
    storeCurrent,
    roomItemList,
    storeList,
    oneDayCheck,
    global,

    // 全局相关
    bWin,
    bLose,
    bLoseing,
    bWined,
    bLosed,
    bCheat,


    uuid,
    hurtNum,
    killNum,
    hero,
    box,

    attackMonster,
    maxAttackNum,
    inputRecord,

    seed,

    cameraHeight,
    cameraAngle,
    resetCameraLoc,

    attributes,
    newestAttrs,

    generateUnitMap,
    catchCompensate,
    oneClickCalls,
    enemyUnits,
    appearanceRecord,
    equipRecord,
    bBlacklist,
    bWhitelist,
    startLoc,
    selectedUnit,
    lastOwnerSelectedUnit,
    lastHurtBoss,
    userId,

    itemShopMap,
    dropRecord,

    // 1 2 3
    archiveIndex,

    // 异步数据
    targetItem,
    targetSpellInfo,
    moveTargetInfo,

    bFollowMouse,
    // windowSize,
}


export class PlayerSourceData {

    //单位相关
    // ClearTimeObj
    [PlayerDataKey.clearFightTime]: { [key: string]: number } = {};
    [PlayerDataKey.petInfo] = [];
    [PlayerDataKey.pet]: UnitModel[] = [];
    [PlayerDataKey.summoned]: UnitModel[] = [];
    [PlayerDataKey.unitCombination]: { [key: string]: CombinationInfo } = {};
    [PlayerDataKey.initUnitPoolData] = [];
    [PlayerDataKey.patro]: UnitModel[] = [];

    // 物品相关
    [PlayerDataKey.goodsBag]: ItemModel[] = [];

    // 任务相关
    [PlayerDataKey.unitApplyTask]: { [taskId: string]: TaskApplyData } = {};

    // 成就相关
    [PlayerDataKey.achievementPetAttr]: Attrs;
    [PlayerDataKey.achievementHeroAttr]: Attrs;
    [PlayerDataKey.achievementSummonAttr]: Attrs;

    // [PlayerDataKey.achievementAttr]: { [key: string]: Attrs } = {};
    [PlayerDataKey.achievements]: { [key: string]: number } = {};
    [PlayerDataKey.handBook]: { [ key: string ]: number } = {};
    [PlayerDataKey.handBookExp]: number = 0;

    [PlayerDataKey.integral]: number = 0;
    [PlayerDataKey.integralCache]: number = 0;


    // 保存相关
    [PlayerDataKey.storeHistory]: SerializeBodyHistory = {
        [ControllerNo.UnitController]: {} as any,
        [ControllerNo.AbilityController]: {} as any,
        [ControllerNo.StoreController]: {} as any,
        [ControllerNo.AchievementController]: {} as any,
        [ControllerNo.GoodController]: {} as any,
        [ControllerNo.TaskController]: {} as any,
    };
    [PlayerDataKey.storeCurrent]: SerializeBodyHistory = {
        [ControllerNo.UnitController]: {} as any,
        [ControllerNo.AbilityController]: {} as any,
        [ControllerNo.StoreController]: {} as any,
        [ControllerNo.AchievementController]: {} as any,
        [ControllerNo.GoodController]: {} as any,
        [ControllerNo.TaskController]: {} as any,
    };
    [PlayerDataKey.roomItemList]: RPGRoomItem | LIVERoomItem = {} as any;
    [PlayerDataKey.storeList]: ControllerNo[] = [];
    [PlayerDataKey.oneDayCheck]: boolean = false;
    [PlayerDataKey.global]: StoreSerializeBody = {} as any;

    [PlayerDataKey.bWin]: boolean = false;
    [PlayerDataKey.bLose]: boolean = false;
    [PlayerDataKey.bWined]: boolean = false;
    [PlayerDataKey.bLosed]: boolean = false;
    [PlayerDataKey.bLoseing]: boolean = false;

    [PlayerDataKey.bCheat]: boolean = false;

    [PlayerDataKey.uuid]: string = '';
    [PlayerDataKey.userId]: string = '';
    [PlayerDataKey.hurtNum]: number = 0;
    [PlayerDataKey.killNum]: number = 0;
    [PlayerDataKey.hero];
    [PlayerDataKey.box];
    [PlayerDataKey.attackMonster]: { [key: string]: number } = {};
    [PlayerDataKey.maxAttackNum]: number = 0;
    [PlayerDataKey.inputRecord]: { [key: string]: number } = {};

    [PlayerDataKey.seed]: number;

    [PlayerDataKey.cameraHeight]: number = 0;
    [PlayerDataKey.resetCameraLoc]: boolean = false;

    [PlayerDataKey.attributes]: { [key: string]: PlayerAttribute } = {};
    [PlayerDataKey.newestAttrs]: PlayerAttribute;

    [PlayerDataKey.generateUnitMap]: { [key: string]: boolean } = {};

    [PlayerDataKey.catchCompensate]: { [key: string]: number } = {};

    [PlayerDataKey.oneClickCalls]: UnitModel[] = [];

    [PlayerDataKey.enemyUnits]: { [handleId: string]: string } = {};

    [PlayerDataKey.appearanceRecord]: { [type: string]: { appId: string, effectModel: EffectModel } } = {};

    [PlayerDataKey.equipRecord]: { [type: string]: { itemId: string, effectModel: EffectModel } } = {};

    [PlayerDataKey.bBlacklist]: number = 0;

    [PlayerDataKey.bWhitelist]: number = 0;

    [PlayerDataKey.startLoc]: LocModel;
    [PlayerDataKey.selectedUnit]: UnitModel;
    [PlayerDataKey.lastOwnerSelectedUnit]: UnitModel;
    [PlayerDataKey.lastHurtBoss]: UnitModel;

    [PlayerDataKey.itemShopMap]: { [key: string]: ItemShopInfo } = {};
    [PlayerDataKey.dropRecord]: { [key: string]: boolean } = {};
    [PlayerDataKey.archiveIndex]: number = 0;

    [PlayerDataKey.targetItem]: ItemModel;
    [PlayerDataKey.targetSpellInfo]: { effect: UnitModel, id: string, bShow: boolean, type: CastType1  } = { effect: undefined, id: undefined, bShow: undefined, type: CastType1.null };
    [PlayerDataKey.moveTargetInfo]: { effect: UnitModel, bShow: boolean, time: number } = { effect: undefined, bShow: undefined, time: 0 };

    [PlayerDataKey.bFollowMouse]: number = 0;

    constructor() {

        const gameType = Configer.getConfig(ConfigKey.gameType);
        if (gameType === GameType.orpg) {
            this[PlayerDataKey.roomItemList] = { fightValue: 0, wave: 0, level: 0 }
        } else {
            this[PlayerDataKey.roomItemList] = { difficult: '无' }
        }

        this[PlayerDataKey.seed] = MathUtil.random(0, 100);
    }
}

export enum UnitActionLevel {
    stand = 1,
    path,
    hatred,
}

export enum UnitDataKey {

    // 马甲信息
    vestJson = 1,
    // 单位最新属性
    newestAttribute,
    // 单位初始化时的属性
    initAttribute,
    // 单位额外属性 通过最新属性减额外属性来将框架附加的属性添加到原生游戏属性之上
    extraAttribute,
    // 永久增减的属性
    subAttribute,
    // 单位曾经等级缓存（切换单位时不会清空）
    maxLvCache,
    // 单位曾经等级缓存（切换单位时清空，目前主要计算属性成长）
    maxLvHistory,
    // 单位词缀
    unitAffix,
    // 单位路径缓存
    pathCache,
    // 单位禁区缓存
    forbiddenCache,


    // 技能相关
    // 记录单位已有技能
    abilitys,
    // 技能增加的属性
    abilityAttribute,
    // 技能持续效果倒计时
    clearAttributeTime,
    // 技能使用频率记录
    abilityFrequency,
    // 技能效果内置冷卻
    abilityRecord,

    // 物品相关
    goodCombination,
    // 物品相关
    // 单位背包
    unitBag,
    // 单位背包序号 主要用来切换背包时使用
    unitBagsIndex,
    // 装备栏
    unitEquip,

    // 伤害计数
    hurtNum,

    // 复活次数
    resumeNum,
    // 复活倒计时  -1 时是活了或者不需要复活
    resumeTime,

    // 正在出战
    bBattle,

    // 主人  用来做宠物巡逻
    master,

    bDead,
    // 状态
    action,
    // 仇恨值集合
    hatredAttackedMap,
    hatredAttackerMap,

    iconPath,
    modelPath,
    modelDefaultPath,
}

export class UnitSourceData {
    // VestJson
    [UnitDataKey.vestJson]: VestJson;
    // Attribute
    [UnitDataKey.newestAttribute]: UnitAttribute;
    [UnitDataKey.extraAttribute]: UnitAttribute;
    [UnitDataKey.subAttribute]: UnitAttribute = new UnitAttribute();

    [UnitDataKey.initAttribute]: Attrs;

    [UnitDataKey.maxLvCache]: number = 1;
    [UnitDataKey.maxLvHistory]: number = 1;
    [UnitDataKey.unitAffix]: any[] = [];
    [UnitDataKey.pathCache]: string;
    [UnitDataKey.forbiddenCache]: string;


    [UnitDataKey.abilitys]: { [key: string]: AbilityJson } = {};
    // Attribute
    [UnitDataKey.abilityAttribute]: { [key: string]: UnitAttribute } = {};
    [UnitDataKey.abilityFrequency]: { [key: string]: number } = {};
    [UnitDataKey.abilityRecord]: { [key: string]: number } = {};

    // CombinationInfo
    [UnitDataKey.goodCombination]: CombinationInfo = {};
    [UnitDataKey.unitBag]: ItemModel[][] = [];
    [UnitDataKey.unitBagsIndex]: number = 0;

    [UnitDataKey.hurtNum]: number = 0;
    [UnitDataKey.resumeNum]: number = 0;
    [UnitDataKey.resumeTime]: number = 0;

    [UnitDataKey.bBattle]: number = 1;
    [UnitDataKey.master]: UnitModel;

    [UnitDataKey.bDead]: number = 0;

    [UnitDataKey.action]: UnitActionLevel = UnitActionLevel.stand;
    // 仇恨来源只需要知道自己打过谁
    [UnitDataKey.hatredAttackerMap]: { [attackedId: string]: boolean } = {};
    // 被攻击者需要知道仇恨来源对自己造成了多少点伤害
    [UnitDataKey.hatredAttackedMap]: { [attackerId: string]: number } = {};


    [UnitDataKey.modelPath]: string;
    [UnitDataKey.iconPath]: string;
    [UnitDataKey.modelDefaultPath]: string;

    [UnitDataKey.unitEquip]: ItemModel[] = [];

    constructor() {
        const maxItemIndex: number = Configer.getConfig(ConfigKey.maxItemIndex);

        const arr: ItemModel[][] = [];
        for (let i = 0; i < maxItemIndex; i++) {
            arr[i] = [];
        }
        this[UnitDataKey.unitBag] = arr;
    }
}

export enum ItemDataKey {
    itemAffix = 1,
    protectTime,
    ownerId,
    seller,
    coolDown,
    num,

    fakeX,
    fakeY,

    pawnable,
    powerup,
    dropInDeath,
    dropAble,

    forgLv,

    sealData,
    // onUnit,
}

export class ItemSourceData {
    [ItemDataKey.itemAffix]: string = '';
    [ItemDataKey.protectTime]: number = 0;
    [ItemDataKey.ownerId]: number = -1;
    [ItemDataKey.seller]: UnitModel;
    [ItemDataKey.coolDown]: number = 0;
    [ItemDataKey.fakeX]: number = 0;
    [ItemDataKey.fakeY]: number = 0;
    [ItemDataKey.num]: number = 0;

    [ItemDataKey.pawnable]: number = 0;
    [ItemDataKey.powerup]: number = 0;
    [ItemDataKey.dropInDeath]: number = 0;
    [ItemDataKey.dropAble]: number = 0;

    [ItemDataKey.forgLv]: number = 0;
    [ItemDataKey.sealData]: UnitJson;
    // [ItemDataKey.onUnit]: UnitModel;
}